package com.buka.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.buka.common.BizCodeEnum;
import com.buka.constants.Constants;
import com.buka.constants.RedisConstants;
import com.buka.entity.Product;
import com.buka.exception.BizException;
import com.buka.interceptor.LoginUserInterceptor;
import com.buka.service.CartService;
import com.buka.service.ProductService;
import com.buka.util.JsonData;
import com.buka.vo.CartItem;
import com.buka.vo.CartVo;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    ProductService productService;

    /***
     *
     * 添加购物车
     *
     *
     * @param cartItem
     * @return
     */

    @Override
    public JsonData add(CartItem cartItem) {
        //有可能在加入购物车时，商品下架了。不允许加入购物车
        Long productId = cartItem.getProductId();
        //校验商品是否存在
        Product product = productService.getById(productId);
        if (null == product) {
            throw new BizException(BizCodeEnum.NOT_PRODUCT);
        }

        /** 设置购物项属性 */
        cartItem.setProductId(product.getId());
        cartItem.setProductImage(product.getCoverImg());
        cartItem.setProductTitle(product.getTitle());
        //折扣单价
        cartItem.setProductPrice(BigDecimal.valueOf(product.getAmount()));
        //原价
        cartItem.setProductOldPrice(BigDecimal.valueOf(product.getOldAmount()));


        //获取购物车中的数据，总价累加
        String cartKey = RedisConstants.CART_KEY + LoginUserInterceptor.threadLocal.get().getId();
        //第一个是redis key的类型  第二个是 HashKey的类型  第三格式HashValue类型
        BoundHashOperations<String, Long, CartItem> cartMap = redisTemplate.boundHashOps(cartKey);
        CartItem cartItem1 = cartMap.get(productId);
        //原购物车中有当前商品信息，数量，总金额累加
        if (cartMap != null && cartItem1 != null) {
            int buyNum = cartItem1.getBuyNum() + cartItem.getBuyNum();
            cartItem.setBuyNum(buyNum);
        }
        //将购买数量转为BigDecimal类型
        BigDecimal buyNum_decimal = BigDecimal.valueOf(cartItem.getBuyNum());
        //计算总价
        BigDecimal totalAmount = cartItem.getProductPrice().multiply(buyNum_decimal);
        BigDecimal totalOldAmount = cartItem.getProductOldPrice().multiply(buyNum_decimal);
        //折扣后总价
        cartItem.setTotalAmount(totalAmount);
        //折扣前总价
        cartItem.setTotalOldAmount(totalOldAmount);
        //直接加入购物车
        cartMap.put(productId, cartItem);

        return JsonData.buildSuccess();
    }

    @Override
    public JsonData list() {
        String redisKey = RedisConstants.CART_KEY+LoginUserInterceptor.threadLocal.get().getId();
        BoundHashOperations cartMap = redisTemplate.boundHashOps(redisKey);
        List<CartItem> cartItemList = cartMap.values();
        //将集合转为map  key 是商品id  value 是购物项
        Map<Long, CartItem> cartItemMap = cartItemList.stream()
                .collect(Collectors.toMap(CartItem::getProductId, Function.identity()));

        //获取购物车中全部商品id
        Set<Long> pidSet = cartItemList.stream().map(CartItem::getProductId).collect(Collectors.toSet());
        LambdaQueryWrapper<Product> productQuery = Wrappers.lambdaQuery(Product.class);
        productQuery.in(Product::getId,pidSet);
        List<Product> productList = productService.list(productQuery);

        //购物车中商品总数
        Integer totalBuyNum = 0;
        //优惠后的支付总价
        BigDecimal totalAmountOfFree = new BigDecimal(0);
        //优惠前的总价格
        BigDecimal totalAmountOfOld = new BigDecimal(0);
        //校验单价
        for (Product product : productList) {
            CartItem cartItem = cartItemMap.get(product.getId());
            double v = cartItem.getProductPrice().doubleValue();
            if(product.getAmount() != v ){
                cartItem.setProductPrice(BigDecimal.valueOf(product.getAmount()));
                //重新计算折扣后总价
                BigDecimal totalAmount = BigDecimal.valueOf(cartItem.getBuyNum()).multiply(cartItem.getProductPrice());
                cartItem.setTotalAmount(totalAmount);

                //重新计算折扣前总价
                BigDecimal oldTotalAmount = BigDecimal.valueOf(cartItem.getBuyNum()).multiply(cartItem.getTotalOldAmount());
                cartItem.setTotalOldAmount(oldTotalAmount);
            }

            totalBuyNum += cartItem.getBuyNum();
            totalAmountOfFree = totalAmountOfFree.add(cartItem.getTotalAmount());
            totalAmountOfOld = totalAmountOfOld.add(cartItem.getTotalOldAmount());
        }
        //购物车总价计算
        CartVo cartVo = new CartVo();
        cartVo.setCartItem(cartItemList);
        cartVo.setTotalAmount(totalAmountOfOld);
        cartVo.setRealPayAmount(totalAmountOfFree);
        cartVo.setTotalNum(totalBuyNum);
        return JsonData.buildSuccess(cartVo);
    }
}
